package com.ethink.warehouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.id.generator.IdGenerator;
import com.ethink.warehouse.api.constant.WarehouseRespCode;
import com.ethink.warehouse.api.enums.LogisticsTransferOrderOrderStatusEnum;
import com.ethink.warehouse.api.info.LogisticsTransferDetailOrderInfo;
import com.ethink.warehouse.api.info.LogisticsTransferOrderInfo;
import com.ethink.warehouse.api.info.MateInventoryDetailInfo;
import com.ethink.warehouse.api.request.*;
import com.ethink.warehouse.api.response.LogisticsTransferOrderAddResponse;
import com.ethink.warehouse.api.response.LogisticsTransferOrderDetailResponse;
import com.ethink.warehouse.api.response.LogisticsTransferOrderQueryItemModeResponse;
import com.ethink.warehouse.api.response.LogisticsTransferOrderQueryResponse;
import com.ethink.warehouse.common.entity.LogisticsTransferDetailOrder;
import com.ethink.warehouse.common.entity.LogisticsTransferOrder;
import com.ethink.warehouse.common.mapper.LogisticsTransferDetailOrderMapper;
import com.ethink.warehouse.common.mapper.LogisticsTransferOrderMapper;
import com.ethink.warehouse.common.mapper.MateInventoryMapper;
import com.ethink.warehouse.converter.LogisticsTransferOrderConverter;
import com.ethink.warehouse.service.LogisticsTransferDetailOrderService;
import com.ethink.warehouse.service.LogisticsTransferOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物流调拨单 Service接口实现
 *
 * @author default
 * @date 2022-11-10
 */
@Slf4j
@Service
public class LogisticsTransferOrderServiceImpl implements LogisticsTransferOrderService {

    @Autowired
    private LogisticsTransferOrderMapper logisticsTransferOrderMapper;

    @Autowired
    private LogisticsTransferDetailOrderMapper logisticsTransferDetailOrderMapper;

    @Autowired
    private MateInventoryMapper mateInventoryMapper;

    @Autowired
    private LogisticsTransferDetailOrderService logisticsTransferDetailOrderService;

    @Autowired
    private IdGenerator idGenerator;

    @Override
    public Page<LogisticsTransferOrderQueryResponse> queryLogisticsTransferOrder(LogisticsTransferOrderQueryRequest request) {
        return logisticsTransferOrderMapper.queryLogisticsTransferOrder(PageUtils.buildPage(request), request);
    }

    @Override
    public LogisticsTransferOrderDetailResponse getLogisticsTransferOrderById(Long logisticsTransferOrderId) {
        LogisticsTransferOrderDetailResponse response = new LogisticsTransferOrderDetailResponse();
        LogisticsTransferOrderInfo logisticsTransferOrderInfo = logisticsTransferOrderMapper.getLogisticsTransferOrderById(logisticsTransferOrderId);
        response.setLogisticsTransferOrderInfo(logisticsTransferOrderInfo);
        // 根据库存ID查数据
        List<LogisticsTransferDetailOrderInfo> detailOrderInfoList = logisticsTransferDetailOrderMapper.listLogisticsTransferDetailOrderByOrderNo(logisticsTransferOrderInfo.getOrderNo());
        List<MateInventoryDetailInfo> mateInventoryDetailInfoList = mateInventoryMapper.listMateInventoryByIdList(detailOrderInfoList.stream().map(LogisticsTransferDetailOrderInfo::getMateInventoryId).distinct().collect(Collectors.toList()));
        Map<Long, MateInventoryDetailInfo> mateInventoryDetailInfoMap = mateInventoryDetailInfoList.stream()
                .collect(Collectors.toMap(MateInventoryDetailInfo::getId, info -> info));
        for (LogisticsTransferDetailOrderInfo detailOrderInfo : detailOrderInfoList) {
            MateInventoryDetailInfo mateInventoryDetailInfo = mateInventoryDetailInfoMap.get(detailOrderInfo.getMateInventoryId());
            detailOrderInfo.setAvailableQty(mateInventoryDetailInfo.getAvailableQty());
        }
        response.setLogisticsTransferDetailOrderInfoList(detailOrderInfoList);
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogisticsTransferOrderAddResponse addLogisticsTransferOrder(LogisticsTransferOrderAddRequest request) {
        LogisticsTransferOrderAddResponse response = new LogisticsTransferOrderAddResponse();
        LogisticsTransferOrder logisticsTransferOrder = new LogisticsTransferOrder();
        BeanUtils.copyProperties(request, logisticsTransferOrder);
        String orderNo = idGenerator.db();
        logisticsTransferOrder.setOrderNo(orderNo);
        logisticsTransferOrder.setOrderStatus(request.getAddType().equals(1) ? LogisticsTransferOrderOrderStatusEnum.S1.getIntValue() : LogisticsTransferOrderOrderStatusEnum.S3.getIntValue());
        logisticsTransferOrderMapper.insert(logisticsTransferOrder);
        List<LogisticsTransferDetailOrder> detailEntityList = new ArrayList<>();
        for (LogisticsTransferOrderAddRequest.LogisticsTransferOrderAddRequestMateItem item : request.getItems()) {
            LogisticsTransferDetailOrder detailEntity = new LogisticsTransferDetailOrder();
            detailEntity.setOrderNo(orderNo);
            detailEntity.setDetailOrderNo(idGenerator.dbDetail());
            detailEntity.setMateInventoryId(item.getMateInventoryId());
            detailEntity.setQty(item.getQty());
            detailEntityList.add(detailEntity);
        }
        logisticsTransferDetailOrderService.saveBatch(detailEntityList);
        response.setId(logisticsTransferOrder.getId());
        LogisticsTransferOrderInfo logisticsTransferOrderInfo = logisticsTransferOrderMapper.getLogisticsTransferOrderById(logisticsTransferOrder.getId());
        List<LogisticsTransferDetailOrderInfo> detailOrderInfoList = logisticsTransferDetailOrderMapper.listLogisticsTransferDetailOrderByOrderNo(logisticsTransferOrderInfo.getOrderNo());
        response.setLogisticsTransferOrderInfo(logisticsTransferOrderInfo);
        response.setLogisticsTransferDetailOrderInfoList(detailOrderInfoList);
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLogisticsTransferOrder(LogisticsTransferOrderUpdateRequest request) {
        LogisticsTransferOrderInfo logisticsTransferOrderInfo = logisticsTransferOrderMapper.getLogisticsTransferOrderById(request.getId());
        if (!logisticsTransferOrderInfo.getOrderStatus().equals(LogisticsTransferOrderOrderStatusEnum.S1.getIntValue())) {
            throw new BusinessException(WarehouseRespCode.LOGISTICS_TRANSFER_ORDER_UPDATE_STATUS_ERR);
        }
        LambdaUpdateWrapper<LogisticsTransferOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LogisticsTransferOrder::getId, request.getId());
        updateWrapper.set(LogisticsTransferOrder::getOrderType, request.getOrderType());
        updateWrapper.set(LogisticsTransferOrder::getInSubWarehouseCode, request.getInSubWarehouseCode());
        updateWrapper.set(LogisticsTransferOrder::getInSubWarehouseName, request.getInSubWarehouseName());
        updateWrapper.set(LogisticsTransferOrder::getOutSubWarehouseCode, request.getOutSubWarehouseCode());
        updateWrapper.set(LogisticsTransferOrder::getOutSubWarehouseName, request.getOutSubWarehouseName());
        updateWrapper.set(LogisticsTransferOrder::getRemark, request.getRemark());
        if (request.getUpdateType() == 2) {
            // 更新类型为：提交
            updateWrapper.set(LogisticsTransferOrder::getOrderStatus, LogisticsTransferOrderOrderStatusEnum.S3.getIntValue());
        }
        logisticsTransferOrderMapper.update(null, updateWrapper);

        // 根据库存ID，删除历史数据，然后新增
        // 明细数据删除
        LambdaQueryWrapper<LogisticsTransferDetailOrder> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(LogisticsTransferDetailOrder::getOrderNo, logisticsTransferOrderInfo.getOrderNo());
        logisticsTransferDetailOrderMapper.delete(detailQueryWrapper);
        // 明细数据新增
        List<LogisticsTransferDetailOrder> detailEntityList = new ArrayList<>();
        for (LogisticsTransferOrderUpdateRequest.LogisticsTransferOrderUpdateRequestMateItem item : request.getItems()) {
            LogisticsTransferDetailOrder detailEntity = new LogisticsTransferDetailOrder();
            detailEntity.setOrderNo(logisticsTransferOrderInfo.getOrderNo());
            detailEntity.setDetailOrderNo(idGenerator.dbDetail());
            detailEntity.setMateInventoryId(item.getMateInventoryId());
            detailEntity.setQty(item.getQty());
            detailEntityList.add(detailEntity);
        }
        logisticsTransferDetailOrderService.saveBatch(detailEntityList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteLogisticsTransferOrder(Long logisticsTransferOrderId) {
        LogisticsTransferOrderInfo logisticsTransferOrderInfo = logisticsTransferOrderMapper.getLogisticsTransferOrderById(logisticsTransferOrderId);
        if (!logisticsTransferOrderInfo.getOrderStatus().equals(LogisticsTransferOrderOrderStatusEnum.S1.getIntValue())) {
            throw new BusinessException(WarehouseRespCode.LOGISTICS_TRANSFER_ORDER_DELETE_STATUS_ERR);
        }

        LambdaUpdateWrapper<LogisticsTransferOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LogisticsTransferOrder::getId, logisticsTransferOrderId);
        updateWrapper.set(LogisticsTransferOrder::getIsDeleted, true);
        logisticsTransferOrderMapper.update(null, updateWrapper);

        LambdaUpdateWrapper<LogisticsTransferDetailOrder> detailUpdateWrapper = new LambdaUpdateWrapper<>();
        detailUpdateWrapper.eq(LogisticsTransferDetailOrder::getOrderNo, logisticsTransferOrderInfo.getOrderNo());
        detailUpdateWrapper.set(LogisticsTransferDetailOrder::getIsDeleted, true);
        logisticsTransferDetailOrderMapper.update(null, detailUpdateWrapper);
    }

    @Override
    public void setLogisticsTransferOrderStatus(LogisticsTransferOrderSetStatusRequest request) {
        LambdaUpdateWrapper<LogisticsTransferOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LogisticsTransferOrder::getId, request.getId());
        updateWrapper.set(LogisticsTransferOrder::getOrderStatus, request.getOrderStatus());
        logisticsTransferOrderMapper.update(null, updateWrapper);
    }

    @Override
    public void cancelLogisticsTransferOrder(Long logisticsTransferOrderId) {
        LambdaUpdateWrapper<LogisticsTransferOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LogisticsTransferOrder::getId, logisticsTransferOrderId);
        updateWrapper.set(LogisticsTransferOrder::getOrderStatus, LogisticsTransferOrderOrderStatusEnum.S1.getIntValue());
        logisticsTransferOrderMapper.update(null, updateWrapper);
    }

    @Override
    public List<String> queryLogisticsTransferDetailOrderNosByOrderNos(List<String> orderNos) {
        return logisticsTransferDetailOrderMapper.queryLogisticsTransferDetailOrderNosByOrderNos(orderNos);
    }

    @Override
    public void updateLogisticsTransferOrderStatus(List<String> request) {
        logisticsTransferOrderMapper.updateLogisticsTransferOrderStatus(request);
    }

    /**
     * 货品模式分页查询
     *
     * @param request
     * @return
     */
    @Override
    public Page<LogisticsTransferOrderQueryItemModeResponse> queryItemModeLogisticsTransferOrder(LogisticsTransferOrderQueryItemModeRequest request) {
        return logisticsTransferOrderMapper.queryItemModeLogisticsTransferOrder(PageUtils.buildPage(request), request);
    }
}
